#include "device.h"
#include "component.h"
#include "motor_bigplus.h"

/* 调试打印接口 */
#define LOCKBIGPLUS_LOG(format, ...)  __OSAL_LOG("[lockbigplus.c] " C_PURPLE format C_NONE, ##__VA_ARGS__)


/* 电机电流采集的ADC通道 */
#define LOCKBIGPLUS_DCI_ADC_CHANNEL					vADC_1

/* 环形缓存长度、大小定义 */
#define LOCK_RING_BUFFER_LEN				(5)

/* 事件 */
#define EVENT_MOTOR_MONITOR                     (0X00000001)  //电机监控事件
#define EVENT_MOTOR_BRAKE						(0X00000002)

/* 电机控制参数 */
#define MOTOR_PARAM_MAX_REPEAT_TIMES			2    	//最大重复次数（上锁/开锁失败后，会自动重复2次）
#define MOTOR_PARAM_DCI_OVERFLOW_SMALL          2000    //小扭力堵转电流2500mA
#define MOTOR_PARAM_DCI_OVERFLOW_LARGE          3500    //大扭力堵转电流3500mA

#define MOTOR_PARAM_STOP_TIME1                  1000    //电机暂停时间1（电机运行正常运行过程中状态切换需要的暂停时间）
#define MOTOR_PARAM_STOP_TIME2                  100     //电机暂停时间2（开锁堵转暂停时间、电机运行流程结束最后的暂停时间）
#define MOTOR_PARAM_TURN_TIMEOUT                8000    //电机正常运行，超时时间
#define MOTOR_PARAM_BACK_TIMEOUT                1500    //电机回拖运行，超时时间
#define MOTOR_PARAM_OPEN_BACK_TIMEOUT           80    //电机回拖运行，超时时间
#define MOTOR_PARAM_DCI_DETECT_DELAY_TIME       80      //电机启动后，电流检测延迟时间
#define MOTOR_PARAM_BRAKE_TIME                  30      //电机刹车时间

/* 电机监测时间间隔 */
#define MOTOR_MONITOR_TIME                      (10)    //电机监测时间间隔 10ms
/* 电机上锁堵转重新操作锁体的时间间隔 */
#define MOTOR_BLOCKED_LOCKED_TIME               (1000)
/* 电机开锁堵转重新操作锁体的时间间隔 */
#define MOTOR_BLOCKED_UNLOCK_TIME               (100)  



/* 锁体状态 */
static enum
{
	LOCK_STA_UNKNOW,    		//未知状态
	LOCK_STA_LOCKING,   		//正在上锁
	LOCK_STA_UNLOCKING, 		//正在开锁
	LOCK_STA_UNLOCKING_BACK, 	//正在开锁回拖
	LOCK_STA_LOCKED,    		//已上锁
	LOCK_STA_UNLOCK,    		//已开锁
	LOCK_STA_UNLOCK_DOOROPEN,	//开门（上锁过程中门开了）自动开锁
	LOCK_STA_LOCKED_REPEAT,		//堵转重新上锁
    LOCK_STA_UNLOCK_REPEAT, 		//堵转重新开锁
	LOCK_STA_UNLOCK_REPEAT_BACK,	//上锁堵转回拖
	LOCK_STA_LOCK_REPEAT_BACK,		//开锁堵转回拖
}lockStatus = LOCK_STA_UNKNOW; 

/* 电机状态类型 */
typedef enum
{
	MOTOR_STA_LOCKED,               //电机上锁状态：上锁
    MOTOR_STA_LOCKED_BACK,          //电机上锁状态：回拖
    MOTOR_STA_LOCKED_BRAKE,         //电机上锁状态：刹车
	MOTOR_STA_UNLOCK,               //电机开锁状态
    MOTOR_STA_UNLOCK_BRAKE,         //电机开锁状态：刹车
	MOTOR_STA_UNLOCK_BACK,          //电机开锁状态：回拖
    MOTOR_STA_STOP,                 //电机停止状态（暂停）
	MOTOR_STA_IDLE,                 //电机空闲
}MotorStatus_enum_t;

/* 电机状态数据 */
static struct
{
	volatile MotorStatus_enum_t current; //电机当前状态	
	volatile uint32_t startTime;         //电机当前状态开始时间
	volatile uint32_t timeout;           //电机当前状态超时时间
}motorStatus = {MOTOR_STA_IDLE, MOTOR_STA_IDLE};


/* 电机运行错误情况 */
volatile static enum
{
	ERR_NO_ERROR,       //无错误
	ERR_LOCK_ERROR,     //锁体错误（电机运转结束时，传感器状态不对）
	
	ERR_LOCKED_TIMEOUT, //上锁超时
	ERR_UNLOCK_TIMEOUT, //开锁超时
	ERR_BACK_TIMEOUT,   //回拖超时
	
	ERR_LOCKED_DCI,     //上锁过流
	ERR_UNLOCK_DCI,     //开锁过流
	ERR_BACK_DCI,       //回拖过流
}motorError = ERR_NO_ERROR;

/* 电机刹车原因类型 */
typedef enum
{
	MOTOR_BRAKE_NO_SOURCE,              //无刹车源
    MOTOR_BRAKE_LOCKED,                 //上锁刹车
    MOTOR_BRAKE_UNLOCK,                 //开锁刹车
}MotorBrakeSource_enum_t;

/* 上锁方向类型 */
typedef enum
{
	LOCKED_DIR_UNKNOWN,                 //未知上锁方向
    LOCKED_DIR_CW,                      //顺时针上锁方向
    LOCKED_DIR_CCW,                     //逆时针上锁方向
}Locked_Dir_enum_t;

/* 锁体控制阶段类型 */
typedef enum
{
	LOCK_CTRL_STEP_INIT,				//初始状态
	LOCK_CTRL_STEP_LOCK,				//上/开锁阶段
    LOCK_CTRL_STEP_BLOCK,				//堵转阶段
    LOCK_CTRL_STEP_BACK,                //回拖阶段
}Lock_Ctrl_Step_enum_t;

/* 锁体模式 */
typedef enum
{
    LOCKED_MODE_NORMAL,                 //普通模式
    LOCKED_MODE_TEST,                   //测试模式
}Locked_Mode_enum_t;

/* 传感器状态类型 */
typedef enum
{
	LOCK_SENSOR_UNKNOW,  				//传感器状态未知
	LOCK_SENSOR_SET,     				//传感器状态：到位（感应到了）
	LOCK_SENSOR_LONG_SET,				//传感器状态：长时间到位（长按）
	LOCK_SENSOR_RESET,   				//传感器状态：未到位（没感应到）
}SensorStatus_enum_t;

typedef struct 
{
    UserAction_enum_t action;   		//动作
    char *name;                 		//传感器名称
}LockSensorAction_t;

/* 锁体传感器状态 */
volatile SensorStatus_enum_t doorSensor = LOCK_SENSOR_UNKNOW;  //门传感器
volatile SensorStatus_enum_t lockedSensor = LOCK_SENSOR_UNKNOW;//上锁传感器
volatile SensorStatus_enum_t unlockSensor = LOCK_SENSOR_UNKNOW;//开锁传感器


/* 中断挂起标志 */
volatile static uint8_t isrPendFlag;        //中断挂起标志
volatile static uint8_t repeatCount;   			//重复上锁计数
volatile static uint8_t reverseCount = 0;		//反转计数(切换方向时发送堵转计数)
volatile static uint8_t alaramFlag = 0;					//报警标志
volatile static uint8_t mechUnlockFlag = 0;				//机械开锁标志
volatile static uint8_t unlockPushFlag = 0;		//开锁过推标志位，已经开锁未回拖，允许再开锁一次


/* 锁体模式 */
__attribute__((unused))  static Locked_Mode_enum_t lockedMode = LOCKED_MODE_NORMAL;

/* 上锁阶段 */
static Lock_Ctrl_Step_enum_t lockedCtrlStep = LOCK_CTRL_STEP_INIT;

/* 电机配置参数 */
static struct
{
    uint8_t init_flag; //初始化标志
    uint8_t torque;    //电机扭力（1：大扭力、0：小扭力）
    uint8_t dir;       //电机方向（1：锁在门的右侧、0：锁在门的左侧）
	
}lock_config;

static RingBufferHandle_t rbHandle = NULL;
static uint8_t lockTypeFlag = LOCK_SUB_TYPE_BIG;	//锁体类型  LOCK_TYPE_BIG：普通的霸王锁体，LOCK_TYPE_BIG_PLUS：带开关检测的霸王锁体

static ErrorStatus LockBigPlus_SetDir_Sub(LockedDir_enum_t ctrl);



static void LockBigPlus_AutoSwitchDir(void)
{
	/*切换锁方向*/
	if(lock_config.dir == LOCKED_DIR_LEFT)
	{
		lock_config.dir = LOCKED_DIR_RIGHT;
	}
	else
	{
		lock_config.dir = LOCKED_DIR_LEFT;
	}
	LockBigPlus_SetDir_Sub((LockedDir_enum_t)lock_config.dir);

}

/**
  * @brief  切换电机状态
  * @note   
  *
  * @param  status：需要切换的状态
  * @param  timeout：该状态的超时时间
  */
static void LockBigPlus_SwitchMotorStatus(MotorStatus_enum_t status, uint32_t timeout)
{
	isrPendFlag++;
	motorStatus.current = status;
	motorStatus.timeout = timeout;
	motorStatus.startTime = OSAL_GetTickCount();
	if (MOTOR_STA_LOCKED_BACK == motorStatus.current)
	{
        /* 上锁回拖 */
        MotorBigPlus_TurnLeft();//上锁回拖操作跟开锁操作控制电机的方向是一致的
	}
    else if (MOTOR_STA_UNLOCK_BACK == motorStatus.current)
	{
        /* 开锁回拖 */
        MotorBigPlus_TurnRight();//开锁回拖操作跟上锁操作控制电机的方向是一致的
    }
	else if (MOTOR_STA_LOCKED_BRAKE == motorStatus.current ||
            MOTOR_STA_UNLOCK_BRAKE == motorStatus.current )
	{
		/* 刹车 */
		MotorBigPlus_Brake();
		
	}
	else if (MOTOR_STA_LOCKED == motorStatus.current)
	{
		/* 电机上锁 */
		MotorBigPlus_TurnRight();
	}
	else if (MOTOR_STA_UNLOCK == motorStatus.current)
	{
		/* 电机开锁 */
		MotorBigPlus_TurnLeft();
	}
	else
	{
		/* 电机停止 */
		MotorBigPlus_Stop();
	}
	isrPendFlag--;
}

/**
  * @brief  处理上锁流程结束
  *         
  * @note   
  */
static void LockBigPlus_MotorLockedEnd(void)
{
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));
	LOCKBIGPLUS_LOG("LockBigPlus_MotorLockedEnd,status:%d,error:%d \r\n",lockStatus,motorError);

	if((lockTypeFlag == LOCK_SUB_TYPE_BIG_PLUS) )	
	{
		/* 检测锁体 */
		if(doorSensor == LOCK_SENSOR_RESET)	//叉舌未检测到
		{
			/* 上锁过程中门开了：自动执行开锁 */
			LOCKBIGPLUS_LOG("The door opened during the locking process\r\n");
			motorError = ERR_NO_ERROR;
			lockStatus = LOCK_STA_UNLOCK_DOOROPEN;
			LockBigPlus_SwitchMotorStatus(MOTOR_STA_UNLOCK, MOTOR_PARAM_TURN_TIMEOUT);
			return;
		}
		else
		{
			if(lockStatus == LOCK_STA_UNLOCK_REPEAT_BACK)
			{
				/* 堵转回拖完后重新上锁 */
				LOCKBIGPLUS_LOG("Block and re-lock");
				repeatCount++;
				motorError = ERR_NO_ERROR;
				lockStatus = LOCK_STA_LOCKED_REPEAT;
				LockBigPlus_SwitchMotorStatus(MOTOR_STA_LOCKED, MOTOR_PARAM_TURN_TIMEOUT);
				return ;
			}

			if ( motorError == ERR_LOCKED_DCI
					&& repeatCount <  MOTOR_PARAM_MAX_REPEAT_TIMES - 1
					&& lockedSensor == LOCK_SENSOR_RESET )
			{
				LOCKBIGPLUS_LOG("Not lock (DCI ERROR)\r\n");

				if(unlockSensor != LOCK_SENSOR_RESET)	
				{
					/* 开锁(剪刀舌)传感器感应到了，方向反了,切换方向 */
					reverseCount++;

					if(reverseCount >= 2)
					{
						/* 切换方向发生了堵转2次，方向恢复原来的方向，执行回拖（在门是虚掩的状态下出现，叉舌按下，剪刀舌按下，上锁未按下）*/
						reverseCount = 0;
						LockBigPlus_AutoSwitchDir();
						lockMsg.lock = LOCK_ACTION_DCI_ERROR;//
						OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
						lockStatus = LOCK_STA_UNLOCK_REPEAT_BACK;
						LockBigPlus_SwitchMotorStatus(MOTOR_STA_LOCKED_BACK, MOTOR_PARAM_OPEN_BACK_TIMEOUT);  //堵转了先回拖
					}
					else
					{
						/* 切换方向，重新上锁 */
						LockBigPlus_AutoSwitchDir();
						motorError = ERR_NO_ERROR;
						LockBigPlus_SwitchMotorStatus(MOTOR_STA_LOCKED, MOTOR_PARAM_TURN_TIMEOUT);
					}

				}
				else
				{
					/* 开锁(剪刀舌)没感应到 */
					lockMsg.lock = LOCK_ACTION_DCI_ERROR;
					OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
					lockStatus = LOCK_STA_UNLOCK_REPEAT_BACK;
					LockBigPlus_SwitchMotorStatus(MOTOR_STA_LOCKED_BACK, MOTOR_PARAM_OPEN_BACK_TIMEOUT); //堵转了先回拖
				}

				return;
			}
			else if(motorError == ERR_LOCKED_DCI
					&& repeatCount >=  MOTOR_PARAM_MAX_REPEAT_TIMES - 1
					&& lockedSensor == LOCK_SENSOR_RESET)
			{
				LOCKBIGPLUS_LOG("Lock After 1 blocking attempts, tow back\r\n");
				/* 堵转尝试1次后，回拖 */
				alaramFlag = 1;
				motorError = ERR_BACK_DCI;
				LockBigPlus_SwitchMotorStatus(MOTOR_STA_LOCKED_BACK, MOTOR_PARAM_OPEN_BACK_TIMEOUT);
				return;
			}

			if(alaramFlag == 1)
			{
				/*上锁堵转后，回拖完成进行报警*/
				alaramFlag = 0;
				lockMsg.lock = LOCK_ACTION_ABNORMAL;
				OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
				motorError = ERR_NO_ERROR;
				motorStatus.current = MOTOR_STA_IDLE;
				OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
				return;
			}

			/* 上锁完成，执行回拖 */
			if(lockedSensor != LOCK_SENSOR_RESET && (lockedCtrlStep != LOCK_CTRL_STEP_BACK))
			{
				reverseCount = 0;
				motorError = ERR_NO_ERROR;
				lockedCtrlStep = LOCK_CTRL_STEP_BACK;		//标记为回拖阶段
				LockBigPlus_SwitchMotorStatus(MOTOR_STA_LOCKED_BACK, MOTOR_PARAM_OPEN_BACK_TIMEOUT);
				return;
			}
		}
		
		
	}
	else
	{
		/* 非检测锁体 */
		/* 上锁堵塞了,执行回拖 */
		if(lockedCtrlStep == LOCK_CTRL_STEP_BLOCK || (lockedCtrlStep == LOCK_CTRL_STEP_LOCK))
		{
			motorError = ERR_NO_ERROR;
			lockedCtrlStep = LOCK_CTRL_STEP_BACK;		//标记为回拖阶段
			LockBigPlus_SwitchMotorStatus(MOTOR_STA_LOCKED_BACK, MOTOR_PARAM_OPEN_BACK_TIMEOUT);
			return;
		}

	}


	lockedCtrlStep = LOCK_CTRL_STEP_INIT;
	
	if(motorError == ERR_LOCKED_TIMEOUT)
	{
		lockMsg.lock = LOCK_ACTION_ABNORMAL;//锁体异常-上锁超时
	}
	else
	{
		lockMsg.lock = LOCK_ACTION_LOCKED;//上锁成功，已回拖
	}
	OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
	motorError = ERR_NO_ERROR;
	motorStatus.current = MOTOR_STA_IDLE;
	OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
}

/**
  * @brief  处理开锁流程结束
  *         
  * @note   
  */
static void LockBigPlus_MotorUnlockEnd(void)
{
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));
	LOCKBIGPLUS_LOG("LockBigPlus_MotorUnlockEnd,Status:%d,error:%d\r\n",lockStatus,motorError);


	if(motorError == ERR_UNLOCK_TIMEOUT)
	{
		lockMsg.lock = LOCK_ACTION_ABNORMAL;//锁体异常-开锁超时
	}
	else
	{
		if(lockTypeFlag == LOCK_SUB_TYPE_BIG)
		{
			lockMsg.lock = LOCK_ACTION_UNLOCK_NO_BACK;//开锁成功,未回拖
		}
		else
		{
			if(lockMsg.lock == LOCK_ACTION_BUSY)
			{
				lockMsg.lock = LOCK_ACTION_UNLOCK_NO_BACK;
			}
			else
			{
				lockMsg.lock = LOCK_ACTION_INVALID;
			}

			if(lockStatus == LOCK_STA_LOCK_REPEAT_BACK)
			{
				/* 开锁堵转，回拖完后，重新开锁 */
				repeatCount++;
				motorError = ERR_NO_ERROR;
				lockStatus = LOCK_STA_UNLOCK_REPEAT;
				LockBigPlus_SwitchMotorStatus(MOTOR_STA_UNLOCK, MOTOR_PARAM_TURN_TIMEOUT);
				return ;
			}
			
			if ( motorError == ERR_UNLOCK_DCI
					&& repeatCount <  MOTOR_PARAM_MAX_REPEAT_TIMES - 1
					&& unlockSensor == LOCK_SENSOR_RESET )
			{
				LOCKBIGPLUS_LOG("Unlock DCI ERROR\r\n");

				if(lockedSensor != LOCK_SENSOR_RESET)
				{
					/* 上锁传感器感应到了，方向反了,切换方向 */
					LockBigPlus_AutoSwitchDir();
					motorError = ERR_NO_ERROR;
					LockBigPlus_SwitchMotorStatus(MOTOR_STA_UNLOCK, MOTOR_PARAM_TURN_TIMEOUT);

				}
				else
				{
					/* 开锁堵转，先回拖 */
					lockStatus = LOCK_STA_LOCK_REPEAT_BACK;
					LockBigPlus_SwitchMotorStatus(MOTOR_STA_UNLOCK_BACK, MOTOR_PARAM_OPEN_BACK_TIMEOUT);
				}
				

				return;
			}
			else if(motorError == ERR_UNLOCK_DCI
					&& repeatCount >=  MOTOR_PARAM_MAX_REPEAT_TIMES - 1
					&& unlockSensor == LOCK_SENSOR_RESET)
			{
				LOCKBIGPLUS_LOG("Unlock After 1 blocking attempts, tow back\r\n");
				/* 堵转尝试1次后，回拖 */
				alaramFlag = 1;
				motorError = ERR_BACK_DCI;
				LockBigPlus_SwitchMotorStatus(MOTOR_STA_UNLOCK_BACK, MOTOR_PARAM_OPEN_BACK_TIMEOUT);
				return;
			}

			if(alaramFlag == 1)
			{
				/* 开锁堵转后，回拖完成进行报警 */
				alaramFlag = 0;
				lockMsg.lock = LOCK_ACTION_ABNORMAL;
				OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
				motorError = ERR_NO_ERROR;
				motorStatus.current = MOTOR_STA_IDLE;
				OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
				return;
			}

			if ( motorError == ERR_UNLOCK_DCI
					&& repeatCount <  MOTOR_PARAM_MAX_REPEAT_TIMES - 1
					&& unlockSensor != LOCK_SENSOR_RESET )
			{
				/* 开锁堵转，开锁（剪刀舌）检测到 ，开锁到了*/
				if(unlockSensor == LOCK_SENSOR_LONG_SET)
				{
					lockMsg.lock = LOCK_ACTION_UNLOCK_NO_BACK;
					OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
				}
				
				motorError = ERR_NO_ERROR;
				motorStatus.current = MOTOR_STA_IDLE;
				OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
				return;
			}
			
		}
		
	}

	/* 上锁中门开了 */
	if(lockStatus == LOCK_STA_UNLOCK_DOOROPEN)
	{
		if(doorSensor == LOCK_SENSOR_RESET)
		{
			/* 叉舌松开了，上锁过程中门开了，重新打开门后，进行回拖 */
			LOCKBIGPLUS_LOG("doors LOCK_SENSOR_UNKNOW %d\r\n",doorSensor);
			lockStatus = LOCK_STA_UNLOCKING_BACK;
			LockBigPlus_SwitchMotorStatus(MOTOR_STA_UNLOCK_BACK, MOTOR_PARAM_OPEN_BACK_TIMEOUT);
			return;
		}
		else
		{
			lockStatus = LOCK_STA_UNLOCKING_BACK;
			LOCKBIGPLUS_LOG("door open run back");
			OSAL_EventRepeatCreate(COMP_LOCK, EVENT_MOTOR_MONITOR, MOTOR_MONITOR_TIME, EVT_PRIORITY_HIGH);
			LockBigPlus_SwitchMotorStatus(MOTOR_STA_UNLOCK_BACK, MOTOR_PARAM_OPEN_BACK_TIMEOUT);
	
		}
		
		
	}

	OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
	motorError = ERR_NO_ERROR;
	motorStatus.current = MOTOR_STA_IDLE;
	OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
}

/**
  * @brief  处理开锁回拖流程结束
  *         
  * @note   
  */
static void LockBigPlus_MotorUnlockBackEnd(void)
{
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));
	LOCKBIGPLUS_LOG("LockBigPlus_MotorUnlockBackEnd\r\n");
	unlockPushFlag = 0;	//回拖清除开锁过推标志

	lockMsg.lock = LOCK_ACTION_UNLOCK_BACK;//开锁成功,已回拖
	OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
	motorError = ERR_NO_ERROR;
	motorStatus.current = MOTOR_STA_IDLE;
	lockStatus = LOCK_STA_UNLOCK;
	OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
}

/**
  * @brief  电机运行结束处理
  *         
  * @note   
  */
static void LockBigPlus_MotorTurnEnd(void)
{
	if((motorError == ERR_BACK_DCI))
	{
		LockMsg_t lockMsg;
		memset(&lockMsg, 0, sizeof(lockMsg));
        LOCKBIGPLUS_LOG("back/reset error, motorError:%d\r\n", motorError);
		if((lockStatus == LOCK_STA_UNLOCKING_BACK) || ((lockStatus == LOCK_STA_UNLOCK_REPEAT_BACK)))
		{
			lockMsg.lock = LOCK_ACTION_ABNORMAL;			//回拖过流
			OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));	//消息上报
		}
		
        OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
        motorError = ERR_NO_ERROR; 
		motorStatus.current = MOTOR_STA_IDLE;
	}

    else if (lockStatus == LOCK_STA_LOCKING || lockStatus == LOCK_STA_LOCKED_REPEAT || lockStatus == LOCK_STA_UNLOCK_REPEAT_BACK)
	{
		/* 处理上锁流程结束 */
        LockBigPlus_MotorLockedEnd();
    }
    else if (lockStatus == LOCK_STA_UNLOCKING || lockStatus == LOCK_STA_UNLOCK_DOOROPEN || lockStatus == LOCK_STA_UNLOCK_REPEAT || lockStatus == LOCK_STA_LOCK_REPEAT_BACK) 
	{
        /* 处理开锁流程结束 */
        LockBigPlus_MotorUnlockEnd();
    }
	else if (lockStatus == LOCK_STA_UNLOCKING_BACK)
	{
        /* 处理开锁回拖流程结束 */
        LockBigPlus_MotorUnlockBackEnd();
    }
}

/**
  * @brief  电机运行超时
  *         
  * @note   
  */
static void LockBigPlus_MotorTimeout(void)
{
	switch (motorStatus.current)
	{
		case MOTOR_STA_LOCKED:      //上锁超时
            motorError = ERR_LOCKED_TIMEOUT; 
            break;
		case MOTOR_STA_UNLOCK:      //开锁超时  
            motorError = ERR_UNLOCK_TIMEOUT; 
            break;
		case MOTOR_STA_LOCKED_BACK: //上锁回拖超时
            motorError = ERR_BACK_TIMEOUT;   
            break;
        case MOTOR_STA_UNLOCK_BACK: //开锁回拖超时
            motorError = ERR_BACK_TIMEOUT;   
            break;
		default: 
            break;
	}
    if (MOTOR_STA_STOP == motorStatus.current)	/* 电机STOP 超时 */     
	{
        LockBigPlus_MotorTurnEnd();
    }
	else if (MOTOR_STA_LOCKED_BRAKE == motorStatus.current)
	{
		if(motorError == ERR_LOCKED_DCI)/* 上锁过流导致的刹车超时 */
		{
			LOCKBIGPLUS_LOG("ERR_LOCKED_DCI\r\n");
			LockBigPlus_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_BLOCKED_LOCKED_TIME);
		}
		else	/*  */
        {
			LOCKBIGPLUS_LOG("motorError != ERR_LOCKED_DCI\r\n");
            LockBigPlus_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);
        }
	}
	else if (MOTOR_STA_UNLOCK_BRAKE == motorStatus.current)
	{
		if (lockStatus == LOCK_STA_UNLOCKING)
		{
			LockBigPlus_MotorTurnEnd(); //开锁成功仅刹车，不停车
		}
		else
		{
			if(motorError == ERR_UNLOCK_DCI)/* 开锁过流导致的刹车超时 */
			{
				LockBigPlus_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_BLOCKED_UNLOCK_TIME);
			}
			else	/*  */
			{
				LockBigPlus_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);
			}
		}
	}
    else
    {
		/* 上锁超时、开锁超时、回拖超时、*/
        LockBigPlus_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);
    }
}

/**
  * @brief  检查电机电流
  *         
  * @note   只有以下三种电机状态，才需要检查电流：
  *         MOTOR_STA_LOCKED：上锁状态
  *         MOTOR_STA_UNLOCK：开锁状态
  *         MOTOR_STA_BACK：回拖状态
  */
static void LockBigPlus_MotorCheckDCI(void)
{
	uint16_t dci, dci_overflow;
	uint8_t overflowCnt = 0;

	switch (motorStatus.current)
	{
		case MOTOR_STA_LOCKED: 
		case MOTOR_STA_UNLOCK: 
		case MOTOR_STA_LOCKED_BACK: 
        case MOTOR_STA_UNLOCK_BACK: 
            break;
		default: 
            return;
	}

    dci_overflow = (lock_config.torque == LOCKED_TORQUE_HIGH) ? MOTOR_PARAM_DCI_OVERFLOW_LARGE : MOTOR_PARAM_DCI_OVERFLOW_SMALL;

    do /* 有过流时：就连续获取10次电流 */
    {
        dci = (uint16_t)Device_Read(LOCKBIGPLUS_DCI_ADC_CHANNEL, NULL, 0, 0);
        dci *= 20; //mV转换成mA（电机驱动串的电阻是0.05Ω）
        overflowCnt++;
    }while (dci >= dci_overflow && overflowCnt < 5);

	if(dci >= dci_overflow)
	{
		LOCKBIGPLUS_LOG("dci:%d   dci_overflow:%d\r\n", dci, dci_overflow);
	}
	// else
	// {
	// 	LOCKBIGPLUS_LOG("dci:%d   dci_overflow:%d\r\n", dci, dci_overflow);
	// }
    

    if (overflowCnt >= 5)
    {
        /* 连续10次过流：标记错误情况，电机进入STOP状态 */
        if (motorStatus.current == MOTOR_STA_LOCKED)//上锁过流
        {
            motorError = ERR_LOCKED_DCI; 
            lockedCtrlStep = LOCK_CTRL_STEP_BLOCK;
            LockBigPlus_SwitchMotorStatus(MOTOR_STA_LOCKED_BRAKE, MOTOR_PARAM_BRAKE_TIME);//上锁过流刹车
        }
        else if (motorStatus.current == MOTOR_STA_UNLOCK)//开锁过流
        {
			motorError = ERR_UNLOCK_DCI;
			unlockPushFlag = 1;	
			// unlockCtrlStep = LOCK_CTRL_STEP_BLOCK;
            LockBigPlus_SwitchMotorStatus(MOTOR_STA_UNLOCK_BRAKE, MOTOR_PARAM_BRAKE_TIME);//开锁过流刹车
        }
		else if (motorStatus.current == MOTOR_STA_LOCKED_BACK)//上锁回拖过流
		{
			motorError = ERR_BACK_DCI; 
            LockBigPlus_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);//回拖过流停止
		}
        else if (motorStatus.current == MOTOR_STA_UNLOCK_BACK)//开锁回拖过流
        {
            motorError = ERR_BACK_DCI; 
            LockBigPlus_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);//回拖过流停止
        }
		else
        {
            LockBigPlus_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);
        }
	}
}

/**
  * @brief  电机运行状态监控（电机监控事件）
  *         
  * @note   监控电机电流、超时
  *         电机状态不等于MOTOR_STA_IDLE时：该函数每间隔10ms运行一次
  */
static void LockBigPlus_MotorMonitor(void)
{
    const uint32_t xTicks = OSAL_GetTickCount();
    uint32_t pastTime;
    pastTime = OSAL_PastTime(xTicks, motorStatus.startTime);    
	if (pastTime >= motorStatus.timeout)
	{
		LockBigPlus_MotorTimeout();    /* 处理电机当前状态超时 */
	}
	else if (pastTime >= MOTOR_PARAM_DCI_DETECT_DELAY_TIME)
	{
		LockBigPlus_MotorCheckDCI();   /* 检查电机运行电流（DCI） */
	}
}

/**
  * @brief  上锁接口函数
  *         
  * @note   
  */
static ErrorStatus LockBigPlus_Locked(void)
{
	lockStatus = LOCK_STA_LOCKING;
	lockedCtrlStep = LOCK_CTRL_STEP_LOCK;

	if(lockTypeFlag == LOCK_SUB_TYPE_BIG)
	{
		OSAL_EventRepeatCreate(COMP_LOCK, EVENT_MOTOR_MONITOR, MOTOR_MONITOR_TIME, EVT_PRIORITY_HIGH);
		LockBigPlus_SwitchMotorStatus(MOTOR_STA_LOCKED, MOTOR_PARAM_TURN_TIMEOUT);
		return SUCCESS;
	}
	else
	{
		if ( (doorSensor == LOCK_SENSOR_SET || doorSensor == LOCK_SENSOR_LONG_SET)
				&& (motorStatus.current == MOTOR_STA_IDLE) )
		{
			if (lockedSensor == LOCK_SENSOR_SET)
			{
				motorError = ERR_NO_ERROR;
				lockStatus = LOCK_STA_LOCKED;//已上锁
			}
			else
			{
				repeatCount = 0;
				OSAL_EventRepeatCreate(COMP_LOCK, EVENT_MOTOR_MONITOR, MOTOR_MONITOR_TIME, EVT_PRIORITY_HIGH);
				LockBigPlus_SwitchMotorStatus(MOTOR_STA_LOCKED, MOTOR_PARAM_TURN_TIMEOUT);
				return SUCCESS;
			}
		}
	}
	

	return ERROR;
}

/**
  * @brief  开锁接口函数
  *         
  * @note   
  */
static ErrorStatus LockBigPlus_Unlock(void)
{
	lockStatus = LOCK_STA_UNLOCKING;

	if(lockTypeFlag == LOCK_SUB_TYPE_BIG)
	{
		OSAL_EventRepeatCreate(COMP_LOCK, EVENT_MOTOR_MONITOR, MOTOR_MONITOR_TIME, EVT_PRIORITY_HIGH);
		LockBigPlus_SwitchMotorStatus(MOTOR_STA_UNLOCK, MOTOR_PARAM_TURN_TIMEOUT);
		return SUCCESS;
	}
	else
	{
		if (motorStatus.current == MOTOR_STA_IDLE)
		{
			/* 开锁传感器（剪刀舌）按下了 ，已经过推了一次，还未回拖，不再执行开锁*/
			if ((unlockSensor == LOCK_SENSOR_SET) || (unlockSensor == LOCK_SENSOR_LONG_SET) && (unlockPushFlag == 1))
			{
				motorError = ERR_NO_ERROR;
				lockStatus = LOCK_STA_UNLOCK; //已处于开锁状态
			}
			else
			{
				/* 1. 正常开门 */
				/* 2. 特殊开门，在门是虚掩状态下，虽然开锁传感器按下了，但剪刀舌并没有完全按下，按开锁键需要允许再开锁 */
				repeatCount = 0;
				OSAL_EventRepeatCreate(COMP_LOCK, EVENT_MOTOR_MONITOR, MOTOR_MONITOR_TIME, EVT_PRIORITY_HIGH);
				LockBigPlus_SwitchMotorStatus(MOTOR_STA_UNLOCK, MOTOR_PARAM_TURN_TIMEOUT);
				return SUCCESS;
			}
		}
	}

	return ERROR;
}

/**
  * @brief  开锁回拖接口函数
  *         
  * @note   
  */
static ErrorStatus LockBigPlus_Unlock_Back(void)
{	
	lockStatus = LOCK_STA_UNLOCKING_BACK;
	LOCKBIGPLUS_LOG("LockBigPlus_Unlock_Back");
	

	OSAL_EventRepeatCreate(COMP_LOCK, EVENT_MOTOR_MONITOR, MOTOR_MONITOR_TIME, EVT_PRIORITY_HIGH);
	LockBigPlus_SwitchMotorStatus(MOTOR_STA_UNLOCK_BACK, MOTOR_PARAM_OPEN_BACK_TIMEOUT);
	
	return SUCCESS;
}


/**
  * @brief  锁体任务 处理用户上锁消息
  * @note   
  *         
  * @param  pMsg：消息指针
  */
static void LockBigPlus_ProcessLockedMsg(void)
{
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));
	if (LockBigPlus_Locked() == SUCCESS)
	{
		/* 电机正在上锁 */
		mechUnlockFlag = 0;
		LOCKBIGPLUS_LOG("User start lock\r\n");
	}
	else
	{
		LOCKBIGPLUS_LOG("unlock fail\r\n");	
		/* 启动开锁失败：锁体正忙、已开锁 */
		if ((doorSensor == LOCK_SENSOR_RESET))				//门没关(门未上锁)
		{
			lockMsg.lock = LOCK_ACTION_NO_LOCKED;			//门未上锁
			OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
		}
		else if (motorStatus.current != MOTOR_STA_IDLE)		/* 锁体正忙 */
		{
			lockMsg.lock = LOCK_ACTION_BUSY;				//锁体正忙
			OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
		}
		else
		{
			mechUnlockFlag = 0;
			lockMsg.lock = LOCK_ACTION_LOCKED;				//上锁成功
			OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));

		}
	}
	
}

/**
  * @brief  锁体任务 处理用户开锁消息
  * @note   
  *         
  * @param  pMsg：消息指针
  */
static void LockBigPlus_ProcessUnlockMsg(void)
{
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));
	if ( LockBigPlus_Unlock() == SUCCESS)
	{
		/* 电机正在开锁 */
		mechUnlockFlag = 1;
		LOCKBIGPLUS_LOG("User start unlock\r\n");
	}
	else
	{
		LOCKBIGPLUS_LOG("unlock fail\r\n");	
		/* 启动开锁失败：锁体正忙、已开锁 */
		if (motorStatus.current != MOTOR_STA_IDLE)			/* 锁体正忙 */
		{
			lockMsg.lock = LOCK_ACTION_BUSY;				//锁体正忙
			OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
		}
		else
		{

			lockMsg.lock = LOCK_ACTION_UNLOCK_NO_BACK;	//开锁成功（开锁流程已结束，未回拖）
			OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
			
		}
	}
}


/* Lock组件API函数类型 */
static ErrorStatus Lock_Ctrl_Sub(LockCtrl_enum_t ctrl)
{
    LockMsg_t lockMsg;
    memset(&lockMsg, 0, sizeof(lockMsg));
    lockedMode = LOCKED_MODE_NORMAL;//标记为正常模式
    LOCKBIGPLUS_LOG("Lock_Ctrl, ctrl = %d\r\n", ctrl);

    if (motorStatus.current != MOTOR_STA_IDLE)//非空闲状态下报锁体繁忙,不能执行锁体操作
    {
        lockMsg.lock = LOCK_ACTION_BUSY;
        OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
        LOCKBIGPLUS_LOG("LOCK_ACTION_BUSY\r\n");
        return ERROR;
    }

    /* 变量置位 */
	lockedCtrlStep = LOCK_CTRL_STEP_INIT;
//	unlockCtrlStep = LOCK_CTRL_STEP_INIT;
	
    switch((uint8_t)ctrl)
    {
        case LOCK_CTRL_LOCKED:
			LockBigPlus_ProcessLockedMsg();
            break;
        case LOCK_CTRL_UNLOCK:
			LockBigPlus_ProcessUnlockMsg();
            break; 
		case LOCK_CTRL_UNLOCK_BACK:
			LockBigPlus_Unlock_Back();
            break; 
        default:
            break;
    }
    return SUCCESS;
}

/* 设置上锁方向的接口 */
static ErrorStatus LockBigPlus_SetDir_Sub(LockedDir_enum_t ctrl)
{
	LOCKBIGPLUS_LOG("LockBigPlus_SetDir: %d\r\n", ctrl);
	MotorBigPlus_SetDirection((uint8_t)ctrl);
	lock_config.dir = (uint8_t)ctrl;
    OSAL_NvWrite(0, &lock_config, sizeof(lock_config));
	return SUCCESS;
}

/* 设置电机扭力的接口 */
static ErrorStatus LockBigPlus_SetTorque_Sub(LockedTorque_enum_t torque)
{
	LOCKBIGPLUS_LOG("LockBigPlus_SetTorque: %d\r\n", torque);
	lock_config.torque = (uint8_t)torque;
	OSAL_NvWrite(0, &lock_config, sizeof(lock_config));
	return SUCCESS;
}



/**
  * @brief  产测模式操作上锁/开锁的接口
  * @note   
  *         
  * @param  testMode：测试模式, LOCK_UNLOCK_TEST_MODE:上锁/开锁测试 MOTOR_TEST_MODE:电机测试
  * @param  data：控制参数
  * @param  dataLen:控制参数的个数
  */
static uint16_t Lock_TestCtrl_Sub(Lock_Test_Mode_enum_t testMode, uint8_t data[], uint8_t dataLen)
{
	lockedMode = LOCKED_MODE_TEST;          //标记为测试模式
	if(testMode == LOCK_UNLOCK_TEST_MODE)	//上锁/开锁测试
    {
		return 0;
	}
	else if(testMode == MOTOR_TEST_MODE)	//电机测试
    {
		if(dataLen < 1)						//电机控制至少要有一个参数
        {
            return 0;
        }
        uint8_t motorCtrl = data[0];
		switch (motorCtrl)
		{
			case 1:
				MotorBigPlus_TurnLeft();
				break;
			case 2:
				MotorBigPlus_TurnRight();
				break;
			case 3:
				MotorBigPlus_Stop();
				break;
			default:
				break;
		}
		return 0;
	}
	else
	{
		return 0;
	}
}



/**
  * @brief  处理门状态改变
  *         
  * @note   
  */
static void LockBigPlus_DoorStatusChange(void)
{
    static FlagStatus powerOnFlag = SET;
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));
    
	if (doorSensor == LOCK_SENSOR_LONG_SET)		//插舌长按	
	{
        // if (powerOnFlag == SET)
        // {
        //     powerOnFlag = RESET;
        //     return;//第一次上电，门关闭不做自动上锁
        // }
		lockMsg.door = USER_ACTION_LONG_PRESS;
		OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
	}
	else
	{
		/* 开门、关门：发消息给主任务 */

		lockMsg.door = (doorSensor == LOCK_SENSOR_RESET) ? USER_ACTION_RELEASE :USER_ACTION_PRESS;
		OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
		
		
		/* 开门处理（正常开门：执行回拖    异常开门：撬锁） */
		if (doorSensor == LOCK_SENSOR_RESET)
		{
			if ( motorStatus.current == MOTOR_STA_IDLE
				&& lockedSensor == LOCK_SENSOR_SET )
			{
				lockMsg.lock = LOCK_ACTION_FORCE_UNLOCK;		//强行开锁（撬锁）
				OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
				// 前板自己会处理
			}
			else
			{
				// Lock824_UnlockBack();//开门自动回拖-接受前板命令进行回拖
			}
            powerOnFlag = RESET;
		}
		else if(doorSensor == LOCK_SENSOR_SET)
		{
			/* 叉舌按下，剪刀舌也是按下 */
			if(lockedSensor == LOCK_SENSOR_SET)
			{
				
			}
		}
	}
}

/**
  * @brief  处理上锁传感器改变
  *         
  * @note   该函数用来判断是否产生机械上锁
  */
static void LockBigPlus_LockedSensorChange(void)
{
    LockMsg_t lockMsg;

	if ( (MOTOR_STA_IDLE == motorStatus.current && lockedSensor == LOCK_SENSOR_SET )
		&& (doorSensor == LOCK_SENSOR_SET || doorSensor == LOCK_SENSOR_LONG_SET) )
	{
		memset(&lockMsg, 0, sizeof(lockMsg));
		
		/* 发消息给主任务：机械上锁 */
		LOCKBIGPLUS_LOG("Mech locked success\r\n");		
		
		lockMsg.lock = LOCK_ACTION_LOCKED_MACH;		//机械上锁成功
		OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
	}
    // else if (MOTOR_STA_IDLE == motorStatus.current && lockedSensor != LOCK_SENSOR_SET)
    // {
	// 	memset(&lockMsg, 0, sizeof(lockMsg));
		
	// 	/* 发消息给主任务：锁状态未知 */
	// 	LOCKBIGPLUS_LOG("Lock status unknow\r\n");		
		
	// 	lockMsg.lock = LOCK_ACTION_UNKNOW;
	// 	OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
    // }
}

/**
  * @brief  处理开锁传感器改变
  *         
  * @note   该函数用来判断是否产生机械开锁
  */
static void LockBigPlus_UnlockSensorChange(void)
{
	static uint8_t flag = 0;
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));
	LOCKBIGPLUS_LOG("unlock sensor lockStatus :%d\r\n",lockStatus);

	if (unlockSensor == LOCK_SENSOR_SET )
	{
		lockMsg.unlocks = USER_ACTION_PRESS;
		
        // if (MOTOR_STA_IDLE == motorStatus.current && (doorSensor == LOCK_SENSOR_LONG_SET) && (lockedSensor == LOCK_SENSOR_RESET) && (mechUnlockFlag==0))
        /* 电机空闲， 叉舌长按， 上锁缩进*/
		if (MOTOR_STA_IDLE == motorStatus.current && (doorSensor == LOCK_SENSOR_LONG_SET) && (lockedSensor == LOCK_SENSOR_RESET))
		{
			/*机械开锁完后只上报一次，后续上锁完才清除标志位，
			  因为在叉舌长按下，剪刀舌的按下松开会又认为是机械开锁，与叉舌和剪刀舌结合的上锁判断逻辑冲突，
			  */
			mechUnlockFlag = 1;		
    		/* 发消息给主任务：机械开锁 */
    		LOCKBIGPLUS_LOG("Mech unlock success\r\n");
			lockMsg.lock = LOCK_ACTION_UNLOCK;		//开锁成功
			OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
        }
        else
        {
            if (lockStatus == LOCK_STA_UNLOCK_DOOROPEN)
            {
                /* 上锁过程中门开了，然后自动执行了开锁成功（开锁流程已结束，未回拖） */
                lockMsg.lock = LOCK_ACTION_NO_LOCKED;	
                OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
            }
            else if(lockStatus != LOCK_STA_LOCKED_REPEAT && lockStatus != LOCK_STA_UNLOCKING_BACK)
            {
                /* 开锁成功（开锁流程已结束，未回拖） */
				if(MOTOR_STA_IDLE != motorStatus.current && (doorSensor != LOCK_SENSOR_SET))
				{
					LOCKBIGPLUS_LOG("lockbigplus unlock success\r\n");
					lockMsg.lock = LOCK_ACTION_UNLOCK_NO_BACK;	
					OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));

				}
				else
				{
					OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
				}

            }
			else
			{
				OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
			}
        }

    }
	else if(unlockSensor == LOCK_SENSOR_LONG_SET)
	{
		LOCKBIGPLUS_LOG(" unlock sensor long press\r\n");
		lockMsg.unlocks =  USER_ACTION_LONG_PRESS;
		OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
	}
	else if(unlockSensor == LOCK_SENSOR_RESET)
	{
		
		//第一次上电不上报
		if((flag == 1) && (MOTOR_STA_IDLE == motorStatus.current) && (doorSensor == LOCK_SENSOR_RESET))
		{
			lockMsg.lock = LOCK_ACTION_UNLOCK_MACH_BACK;
		}
		flag = 1;
		LOCKBIGPLUS_LOG(" unlock sensor release\r\n");
		
		lockMsg.unlocks =  USER_ACTION_RELEASE;
		OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
	}
}

/**
  * @brief  处理传感器状态改变
  *         
  * @note   
  */
static void LockBigPlus_ProcessSensorStatusChange(void)
{
	__EFRAM static SensorStatus_enum_t lastDoorSensor = LOCK_SENSOR_UNKNOW;
	__EFRAM static SensorStatus_enum_t lastLockedSensor = LOCK_SENSOR_UNKNOW;
	__EFRAM static SensorStatus_enum_t lastUnlockSensor = LOCK_SENSOR_UNKNOW;
	__EFRAM static uint8_t flag = 0;

	if(flag == 0 && lockTypeFlag == LOCK_SUB_TYPE_BIG_PLUS)
	{
		flag = 1;
		LockMsg_t lockMsg;
		memset(&lockMsg, 0, sizeof(lockMsg));
		lockMsg.type = LOCK_SUB_TYPE_BIG_PLUS;
		OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
	}
	
	if (lastLockedSensor != lockedSensor)
	{
		lastLockedSensor = lockedSensor;
		LockBigPlus_LockedSensorChange();
	}
	
	if (lastUnlockSensor != unlockSensor)
	{
		lastUnlockSensor = unlockSensor;
		LockBigPlus_UnlockSensorChange();
	}
	
	if (lastDoorSensor != doorSensor)
	{
		lastDoorSensor = doorSensor;
		LockBigPlus_DoorStatusChange();
	}

}

/**
  * @brief  门传感器动作
  * @note   
  *         
  * @param  status：门传感器状态
  *         1：传感器到位
  *         0：未到位
  */
static void LockBigPlus_DoorSensorAction(UserAction_enum_t status)
{
	if (status == USER_ACTION_RELEASE)
	{
		/* 已开门 */
		doorSensor = LOCK_SENSOR_RESET;
	}
	else if (status == USER_ACTION_PRESS)
	{
		/* 已关门 */
		doorSensor = LOCK_SENSOR_SET;
	}
	else if (status == USER_ACTION_LONG_PRESS)
	{
		/* 长时间关门 */
		doorSensor = LOCK_SENSOR_LONG_SET;
	}
}

/**
  * @brief  开锁传感器动作
  * @note   
  *         
  * @param  status：开锁传感器状态
  *         1：传感器到位
  *         0：未到位
  */
static void LockBigPlus_UnlockSensorAction(UserAction_enum_t status)
{
	if (status == INPUT_PORT_STA_PRESS)
	{
		unlockSensor = LOCK_SENSOR_SET;

		if (MOTOR_STA_UNLOCK == motorStatus.current)
		{
			/* 切换电机状态 */
			OSAL_EventSingleCreate(COMP_LOCK, EVENT_MOTOR_BRAKE, 50, EVT_PRIORITY_HIGH);
			// LockBigPlus_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);
		}
		else if(MOTOR_STA_LOCKED == motorStatus.current)
		{

		}
		else if(MOTOR_STA_LOCKED_BACK == motorStatus.current) //上锁堵转，后执行回拖到开锁了
		{
			LockBigPlus_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);
		}

	}
	else if (status == INPUT_PORT_STA_RELEASE)
	{
		unlockSensor = LOCK_SENSOR_RESET;

	}
	else if (status == INPUT_PORT_STA_LONG_PRESS)
	{
		unlockSensor = LOCK_SENSOR_LONG_SET;
	}
}

/**
  * @brief  上锁传感器动作
  * @note   
  *         
  * @param  status：上锁传感器状态
  *         1：传感器到位
  *         0：未到位
  */
static void LockBigPlus_LockedSensorAction(UserAction_enum_t status)
{
	if (status == INPUT_PORT_STA_PRESS)
	{
		lockedSensor = LOCK_SENSOR_SET;

		if (MOTOR_STA_LOCKED == motorStatus.current)
		{
			/* 切换电机状态 */
			// OSAL_EventSingleCreate(COMP_LOCK, EVENT_MOTOR_BRAKE, 50, EVT_PRIORITY_HIGH);
			// LockBigPlus_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);
		}
		else if(MOTOR_STA_UNLOCK == motorStatus.current)
		{

		}
	}
	else if (status == INPUT_PORT_STA_RELEASE)
	{
		lockedSensor = LOCK_SENSOR_RESET;
	}
}

static void LockBigPlus_ProcessISR(void)
{
   	LockSensorAction_t sensor;

	isrPendFlag++;
	while (OSAL_RingBufferRead(rbHandle, &sensor) == SUCCESS)
	{
		LOCKBIGPLUS_LOG("%s: action:%d\r\n", sensor.name, sensor.action);

		/* 保存传感器状态、切换电机状态 */
		if (strcmp(sensor.name, "L_DOOR") == 0)
		{
			// printf("\r\nL_lock\r\n");
			LockBigPlus_DoorSensorAction(sensor.action);
		}
		else if (strcmp(sensor.name, "L_UNLOCK") == 0)
		{
			// printf("\r\nL_unlock\r\n");
			LockBigPlus_UnlockSensorAction(sensor.action);
		}
		else if (strcmp(sensor.name, "L_LOCKED") == 0)
		{
			// printf("\r\nL_locked\r\n");
			LockBigPlus_LockedSensorAction(sensor.action);
		}
	}
	isrPendFlag--;
}

/**
  * @brief  锁体传感器中断 回调
  *         
  * @note   该函数以回调形式，在底层的中断函数里面调用
  */
static void LockBigPlus_SensorStatusChange(char *name, uint8_t status, uint8_t times)
{
	LockSensorAction_t sensor;

	/* 锁体传感器动作暂存缓存区 */
	sensor.name = name;
	sensor.action = (UserAction_enum_t)status;
	OSAL_RingBufferWrite(rbHandle, &sensor);

	//TODO 产生了按键中断，推送锁类型给应用层
	if(lockTypeFlag == LOCK_SUB_TYPE_BIG && times != 0xff)
	{
		lockTypeFlag = LOCK_SUB_TYPE_BIG_PLUS;
		
	}

    /* 产生ISR事件 */
    OSAL_EventCreateFromISR(COMP_LOCK);
    printf("\r\nlock-action:%d,name:%s,times:%d\r\n",status,name,times);
 
    // if (isrPendFlag == 0)
    // {
    //     LockBigPlus_ProcessISR();
    // }
}

/**
  * @brief  锁体启动
  *         
  * @note   
  */
static void LockBigPlus_Start(void)
{
	static uint8_t initFlag = 0;
    if (initFlag == 0)
    {
		initFlag = 1;

        OSAL_NvRead(0, &lock_config, sizeof(lock_config));
        if (lock_config.init_flag != 0xFA)
        {
            lock_config.init_flag = 0xFA; //首次上电
            lock_config.torque = LOCKED_TORQUE_SMALL;   //默认扭力：小
            lock_config.dir = LOCKED_DIR_LEFT;          //默认方向：左
            OSAL_NvWrite(0, &lock_config, sizeof(lock_config));
        }

        MotorBigPlus_SetDirection(lock_config.dir);

    }
	LOCKBIGPLUS_LOG("lockbigplus dir is %d",lock_config.dir);
	
	if (rbHandle == NULL)
    {
		/* 创建环形缓存（暂存传感器状态） */
        rbHandle = OSAL_RingBufferCreate(LOCK_RING_BUFFER_LEN, sizeof(LockSensorAction_t));
		/* 注册锁体传感器端口 */
		InputPort_stu_t sensor_list[] = {
			{"L_DOOR",		vPIN_B25, 	INPUT_PORT_LOGIC_LOW, 	INPUT_PORT_FUNC_SINGLE},//LOCK_OP2 -- 插舌感应
			{"L_LOCKED",	vPIN_B26, 	INPUT_PORT_LOGIC_LOW, 	INPUT_PORT_FUNC_SINGLE}, //LOCK_SLOT  -- 主锁舌感应(上锁到位感应)
			{"L_UNLOCK",	vPIN_B28, 	INPUT_PORT_LOGIC_LOW, 	INPUT_PORT_FUNC_SINGLE}, //LOCK_OP1  -- 斜舌感应(开锁到位感应)
		};
		InputPort_Registered(sensor_list, OSAL_LENGTH(sensor_list), LockBigPlus_SensorStatusChange);
	}
    InputPort_EnableProt("L_DOOR");
    InputPort_EnableProt("L_UNLOCK");
    InputPort_EnableProt("L_LOCKED");

	OSAL_EventSingleCreate(COMP_LOCK, EVENT_SYS_ISR, 0, EVT_PRIORITY_HIGH);  
}


static void LockBigPlus_ProcessMbox(uint8_t *msg)
{
    switch (msg[0])
    {
			//控制锁开关
		case LOCK_MBOX_CTRL:
		{
			uint8_t ctrl;
			ctrl = msg[1];
			Lock_Ctrl_Sub((LockCtrl_enum_t)ctrl);
		}
			break;

			//设置方向
		case LOCK_MBOX_SET_DIR:
		{
			uint8_t dir;
			dir = msg[1];
			LockBigPlus_SetDir_Sub((LockedDir_enum_t)dir);
		}
			break;

			//设置电机扭力
		case LOCK_MBOX_SET_TORQUE:
		{
			uint8_t torque;
			torque = msg[1];
			LockBigPlus_SetTorque_Sub((LockedTorque_enum_t)torque);
		}
			break;

			//测试操作
		case LOCK_MBOX_TESTCTRL:
		{
			uint8_t testMode, dataLen, data[10];
			testMode = msg[1];
			dataLen = msg[2];
			memcpy(data, &msg[3], dataLen);
			Lock_TestCtrl_Sub((Lock_Test_Mode_enum_t)testMode, data, dataLen);
		}
			break;
		default:
			
			break;
    }
}


/**
  * @brief  锁体休眠
  *         
  * @note   
  */
static void LockBigPlus_Sleep(void)
{

}


/**
  * @brief  锁体任务函数
  *
  * @note
  *         
  * @param  event：当前任务的所有事件
  *
  * @return 返回未处理的事件
  */
static uint32_t LockBigPlus_Task(uint32_t event)
{
	/* 系统启动事件 */
	if (event & EVENT_SYS_START)
	{
		LOCKBIGPLUS_LOG("Lock task start\r\n");
		Device_Enable(vPIN_C0);
		Device_Enable(vADC_1);
        LockBigPlus_Start();
		return ( event ^ EVENT_SYS_START );
	}
	
	if (event & EVENT_SYS_MBOX)
    {
        uint8_t buffer[30] = {0};
        while (OSAL_MboxAccept(buffer))
        {
            LockBigPlus_ProcessMbox(buffer);
        }
        return ( event ^ EVENT_SYS_MBOX );
    }
	
	/* 系统休眠事件 */
	if (event & EVENT_SYS_SLEEP)
	{
        LOCKBIGPLUS_LOG("Lock task sleep\r\n");
		Device_Disable(vPIN_C0);
		Device_Disable(vPIN_B25);   //切换io口的上下拉状态
		Device_Disable(vPIN_B26);
		Device_Disable(vPIN_B28);
		Device_Disable(vADC_1);
        LockBigPlus_Sleep();
		return ( event ^ EVENT_SYS_SLEEP );
	}
	
	/* 系统中断事件 */
	if (event & EVENT_SYS_ISR)
	{
		LockBigPlus_ProcessISR();
		LockBigPlus_ProcessSensorStatusChange();
		return ( event ^ EVENT_SYS_ISR );
	}

    /* 电机监控事件 */
    if (event & EVENT_MOTOR_MONITOR)
	{
		LockBigPlus_MotorMonitor();
        if (motorStatus.current != MOTOR_STA_IDLE)//非空闲状态下不允许休眠
        {
            OSAL_SetTaskStatus(TASK_STA_ACTIVE);
        }
        else
        {
            OSAL_SetTaskStatus(TASK_STA_NORMAL);
        }
        return ( event ^ EVENT_MOTOR_MONITOR );
    }

	if(event & EVENT_MOTOR_BRAKE)
	{
		if(MOTOR_STA_UNLOCK == motorStatus.current)
		{
			LockBigPlus_SwitchMotorStatus(MOTOR_STA_UNLOCK_BRAKE, MOTOR_PARAM_BRAKE_TIME);
		}
		else if(MOTOR_STA_LOCKED == motorStatus.current)
		{
			LockBigPlus_SwitchMotorStatus(MOTOR_STA_LOCKED_BRAKE, MOTOR_PARAM_BRAKE_TIME);
		}
		
		return (event ^ EVENT_MOTOR_BRAKE);
	}

	return 0;
}
COMPONENT_TASK_EXPORT(COMP_LOCK, LockBigPlus_Task, 4);
